package city.spring.endpoint;

import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.KeyUse;
import com.nimbusds.jose.jwk.RSAKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpoint;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.security.KeyPair;
import java.security.interfaces.RSAPublicKey;
import java.util.Map;

/**
 * jwk端点。为资源服务器提供 JWK 方式验证令牌是否有效的途径
 *
 * @author HouKunLin
 * @date 2019/12/3 0003 21:16
 */
@FrameworkEndpoint
public class JwkSetEndpoint {
    private static final Logger logger = LoggerFactory.getLogger(JwkSetEndpoint.class);
    private final Map<String, Object> jsonObject;

    public JwkSetEndpoint(KeyPair keyPair) {
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAKey.Builder builder = new RSAKey.Builder(publicKey);
        builder
                .keyUse(KeyUse.SIGNATURE)
                // 该 ID 需要与 city.spring.configure.security.CustomJwtAccessTokenConverter 第 34 行的 ID 保持一致
                .keyID("oauth-jwk-key-id");
        RSAKey key = builder.build();
        this.jsonObject = new JWKSet(key).toJSONObject();
    }

    @GetMapping("/.well-known/jwks.json")
    @ResponseBody
    public Map<String, Object> getKey() {
        logger.debug("加载jwks信息: {}", jsonObject);
        return jsonObject;
    }
}
